/**
 * @class NG.controllers.SearchView
 * @extends Ext.Controller
 * 
 * SearchView controller object. All searching operations are handeled by this class.<br>
 * Search view is a Carousel panel. It has two child items. One is result of fad list. Other is details of fad which is selected.
 */
NG.controllers.SearchView = Ext.extend(Ext.Controller, {

	/**
	 * Slide back and forth between different child items of search view. 
	 * @param {Object} options
	 */
    back: function(options) {
    	var layout = app.views.searchView.getCarousel().layout;
		if (layout.getActiveItem().itemId === 'countList') {
			app.views.searchView.activate(1);
         } else if (layout.getActiveItem().itemId === 'resultList') {
 			app.views.searchView.activate(0);
         } else {
  			app.views.searchView.activate(1);
         }
    },
    
    /**
     * Sets getInfoExCommand of view and displays list on search view.<br>
     * <b>options</b> param consists of<br>
     * <li>infoList: Array. Array of NG.models.Info objects.
     * <li>getInfoExCommand: NG.command.GetInfoEx. Used in info detail search.
     * 
     * @param {Object} options
     */
    listInfoList: function (options) {
    	var infoList = options.infoList;
    	var getInfoExCommand = options.getInfoExCommand;
    	app.views.searchView.clear();
    	app.views.searchView.renderInfoList(infoList);
    	app.views.searchView.setGetInfoExCommand(options.getInfoExCommand);
    },
    
    /**
     * Searchs for details when info list row is selected.
     * <b>options</b> param consists of<br>
     * <li>fad: String.
     * @param {Object} options
     */
    listInfoDetail: function (options){
    	
    	app.views.searchView.prepareForNewDetailSearch();  	
    	
    	var infoRecord = options.info;
    	if (!Ext.isEmpty(infoRecord.getDetailCache())) {
    		app.views.searchView.renderInfoDetailList(infoRecord.getDetailCache());
    		NGLogger.info("Detail List retrieved from cache");
    		return;
    	}
    	
    	var getinfoex = app.views.searchView.getGetInfoExCommand();

    	var fad = options.fad;

    	//Initial fad list will be inserted after the command has been posted
    	//It can be used for other queries.
    	var initialFadList = getinfoex.FAD;
    	var workspace = getinfoex.workspace;
    	var fadList = []; //This will be and array consists of one fad.
    	for ( var i = 0; i < getinfoex.FAD.length; i++) {
			if (getinfoex.FAD[i].getTableName() == fad) {
		    	fadList.push(getinfoex.FAD[i]);
		    	break;
			}
		}
    	
    	getinfoex.FAD = fadList; 
    	getinfoex.countOnly = "False";
    	
    	function doInfoDetailList (sessionID){
    		NGServiceRequester.executeCommand(getinfoex, sessionID, {
    	    	requestFinished: function (response) {
    	    		getinfoex.FAD = initialFadList;
    	    		var getInfoExResponse = getinfoex.getResponse(response);
    	    		var infoList = getInfoExResponse.getInfoList();
    	    		var detailList = infoList[0].getDetailList();
    	    		for ( var i = 0; i < detailList.length; i++) {
						detailList[i].prepareHTMLContent();
					}
    	    		infoRecord.setDetailCache(detailList);
    	    		app.views.searchView.renderInfoDetailList(detailList);
    	    	}
    	    });    		
    	}
    	
		var session = NGServiceRequester.isAlreadyLoggedIn(workspace.getUsername(), workspace.getLoginUrl());
		if (session) {
			doInfoDetailList(session.sessionID);
		} else {
			NGServiceRequester.login(ws.getUsername(), workspace.getPassword(), workspace.getLoginUrl(), {
				loginSuccess: function(sessionID) {
					doInfoDetailList(sessionID);
				},
				loginFail: function(response) {
    	    		getinfoex.FAD = initialFadList;
					alert("Login Failed");
				}
			});
		}
    },
    
    /**
     * Called when info detail list item is selected.<br>
     * Point, polygon or path is drawn on the map according to selected fad.
     * <b>options</b> param consists of<br>
     * <li>infoDetail: NG.models.InfoDetail.
     * @param {Object} options
     */
    gotoMap: function (options) {
    	var infoDetail = options.infoDetail;
    	var geometry = infoDetail.getGeometry();
    	if (geometry instanceof NG.models.NGPolygon) {
        	Ext.dispatch({
        		controller: app.controllers.mapView,
        		action: 'drawPolygon',
        		polygon: geometry 
        	});    		
    	} else if (geometry instanceof NG.models.NGPoint){ //point
    		var point = geometry.getCoordinates()[0].createPoint();
        	Ext.dispatch({
        		controller: app.controllers.mapView,
        		action: 'addMarker',
        		point: point, //TODO sina, bu point işini getinfoex'de point okurken hallet
        		htmlContent: infoDetail.getHTMLContent(),
        		title: infoDetail.getParent().getFeatureName(),
        		infoDetail: options.infoDetail
        	});    		
    	} else if (geometry instanceof NG.models.NGLine){ //line
    		var coorPointArray = geometry.getCoordinates(); //NGCoordinate array
    		var pointArray = [];
    		for ( var i = 0; i < coorPointArray.length; i++) {
    			if (Ext.isEmpty(coorPointArray[i].getLat()) || Ext.isEmpty(coorPointArray[i].getLon())) {
    				continue;
    			}
				pointArray.push(coorPointArray[i].createPoint());
			}
        	Ext.dispatch({
        		controller: app.controllers.mapView,
        		action: 'drawPath',
        		pointArray: pointArray, //TODO sina, bu line işini getinfoex'de point okurken hallet
        		centered: true
        	});    		
    	}
    },
    
    /**
     * Searchs fads or selected fad with the entered text. Call mapView controller getInfoEx method.
     * <b>options</b> param consists of<br>
     * <li>text: String.
     * <li>workspace: NG.models.Workspace
     * @param {Object} options
     */
    searchWithText: function (options) {
    	var text = options.text;
    	var workspace = options.workspace;
    	if (Ext.isEmpty(text)) {
    		return;
    	}
    	
		var getinfoex = new NG.command.GetInfoEx({
			workspace: workspace,
			runXmlUrl: workspace.getRunXmlUrl(),
			workspaceName: workspace.getName(),
			SRID: '', //workspace.getSRID(),
			proj: '',
			//FAD: fadList,
			clockwise: 'False',
			//countOnly: fadList.length === 1 ? 'False' : 'True',
			//intersects: options.intersects,
			isLike: {
				propertyName: 'csw:AnyText',//'MAHALLE_ADI',
				propertyLiteral: options.text
			}
		});
		
		Ext.dispatch({
			controller: app.controllers.mapView,
			action: 'getInfoEx',
			workspace: workspace,
			getinfoex: getinfoex
		});
    },
    
    /**
     * Removes or updates info detail item. Calls InfoViewController actions<br>
     * <b>options</b> param consists of<br>
     * <li>operation: Ext.data.Model. This is record of <b>FadOpe</b>
     * <li>infoDetail: NG.models.InfoDetail. Which fad will be deleted or updated.
     * @param {Object} options
     */
    itemAction: function (options){
    	var action = null;
    	var editable = true;
    	if (options.operation.isDelete()) {
    		action = 'deleteFAD';
    		editable = true;
    	} else if (options.operation.isUpdate()) {
    		action = 'viewDetailOfFAD';
    		editable = true;
    	} else if (options.operation.isViewDetail()) {
    		action = 'viewDetailOfFAD';
    		editable = false;
    	}
		Ext.dispatch({
			controller: app.controllers.infoView,
			action: action,
			infoDetail: options.infoDetail,
			editable: editable
		});
    },
    
    /**
     * Refreshs info list and info detail list after the putinfoex request completes.<br/>
     * If update command is completed info detail row is updated. If delete command is completed info detail row is deleted from store and view
     * and info list is updated with the new record count. Actually it is decreased by one.
     * <b>options</b> param consists of<br>
     * <li>comamnd: NG.command.PutInfoEx
     * 
     * @param {Object} options
     */
    refreshViewsAfterPutInfoEx: function (options) {
    	var command = options.command;
    	if (command.dmlType === 'insert') {
    		return;
    	}
		var infoDetailList = app.views.searchView.getInfoDetailList();
		var infoList = app.views.searchView.getInfoList();
		var infoDetail = command.infoDetail;
		var info = infoDetail.getParent();
		if (command.dmlType === 'delete') {
			infoDetailList.getStore().remove(command.infoDetail);
			info.removeDetail(command.infoDetail);
			//Find info in infoList and decrease rowsCount property by one finally refresh the related node.
			for ( var i = 0; i < infoList.getStore().getCount(); i++) {
				var infoTemp = infoList.getStore().getAt(i);
				if (infoTemp.getFeatureName() === info.getFeatureName()) {
					infoTemp.setRowsCount(infoTemp.getRowsCount() - 1);
					infoList.refreshNode(i);			
					break;
				}
			}
		} else if (command.dmlType === 'update') {
			var modifiedFieldsMap = command.modifiedFields;
	    	var fieldNameArray = modifiedFieldsMap.getKeys();
	    	for ( var i = 0; i < fieldNameArray.length; i++) {
	    		var fieldName = fieldNameArray[i];
	    		var value = modifiedFieldsMap.get(fieldName);
	    		infoDetail.setValueOfProperty(fieldName, value);
	    		infoDetail.prepareHTMLContent();
			}
	    	//TODO related infodetaillist row index can be found and refreshNode(index) method can be called for performance 
    		infoDetailList.refresh();
		}    	
    }
});

/**
 * @singleton {NG.controllers.SearchView} app.controllers.searchView 
 */
app.controllers.searchView = new NG.controllers.SearchView();